package vn.sunnet.backviet01.game.coloa.human.enemy;

import org.anddev.andengine.entity.modifier.MoveModifier;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.util.MathUtils;

import vn.sunnet.backviet01.game.coloa.constant.Constants;

public class FlyingDragon extends MinisterEnemy {

	private static final long[] durationFly = { 50, 50, 50, 50, 50, 50, 50, 50,
			50, 50, 50 };
	private static final long[] durationFireSkill = { 100, 100, 150, 150, 300,
			350, 450 };
	private static final long[] durationMoveBackNormal = { 100, 100, 100, 100,
			100, 100, 100, 100, 100, 100, 100 };
	private static final long[] durationDie = { 200, 250, 300, 400 };

	private final TiledTextureRegion mAttackTextureRegion;
	private final TiledTextureRegion mDieTextureRegion;

	private boolean isChecked = false;
	private boolean isMoveBackNormal = false;
	private boolean isFire = false;
	private boolean isAttack = false;
	private boolean isMove = false;

	private long lastFire = 0;
	private long dieTime = 0;

	private StatesFlyingDragon mState;

	private static final float VELOCITY_X = -120;
	private static final float VELOCITY_Y = 0;
	private static final float VELOCITY_X_MOVE_BACK_NORMAL = 120;
	private static final float VELOCITY_Y_MOVE_BACK_NORMAL = 20;

	public FlyingDragon(int tiledAttack, float pX, float pY,
			TiledTextureRegion pTiledTextureRegion,
			TiledTextureRegion pAttackTextureRegion,
			TiledTextureRegion pDieTextureRegion) {
		super(tiledAttack, pX, pY, pTiledTextureRegion);
		this.mAttackTextureRegion = pAttackTextureRegion;
		this.mDieTextureRegion = pDieTextureRegion;
		this.name = Constants.FLYING_DRAGON;
		mState = StatesFlyingDragon.MOVE;
		status = Constants.MOVE;
		animate(durationFly, 0, 10, true);
		handler.setVelocity(VELOCITY_X, VELOCITY_Y);
	}

	public void onManagedUpdate(float pSecondsElapsed) {
		if (checkHideBeat()) {
			mState = StatesFlyingDragon.HIDE_BEAT;
			setVisible(true);
			unregisterUpdateHandler(handler);
			isAttack = false;
			isChecked = false;
			tiledAttack = 8;
		} else if (checkFire()) {
			StatesFlyingDragon pState = getMethodAttack();
			lastFire = System.currentTimeMillis();
			if (pState == StatesFlyingDragon.FIRE) {
				unregisterUpdateHandler(handler);
				fire();
			} else if (pState == StatesFlyingDragon.HIDE) {
				// this.setVisible(false);
			}
		} 
		if (mState == StatesFlyingDragon.FIRE)
			if (this.getCurrentTileIndex() == tiledAttack) {
				if (!isChecked) {
					isFire = true;
					isChecked = true;
				}
			} else
				isChecked = false;
		else if (mState == StatesFlyingDragon.HIDE_BEAT) {
			if (this.getCurrentTileIndex() == tiledAttack) {
				if (!isChecked) {
					isAttack = true;
					isChecked = true;
				}
			} else
				isChecked = false;
		} else if (mState == StatesFlyingDragon.DIE) {
			setAlpha(getAlpha() - 0.02f);
		}

		if (isMoveBackNormal)
			if (getX() > 600) {
				move();
				isMoveBackNormal = false;
			}

		if (isMove && mState != StatesFlyingDragon.MOVE) {
			isMove = false;
			move();
		}

		super.onManagedUpdate(pSecondsElapsed);

		this.xContain = this.getX() + 50;
		this.yContain = this.getY() + 150;
		this.xBottom = this.getX() + this.getWidth() / 2;
		this.yBottom = this.getY() + 230;
	}

	private boolean checkFire() {
		if (this.getX() <= Constants.XPOS_FIRE_FLYINGDRAGON
				&& this.getX() > Constants.XPOS_FIRE_FLYINGDRAGON - 50
				&& lastFire + 5000 < System.currentTimeMillis()
				&& mState != StatesFlyingDragon.MOVE_BACK) {
			return true;
		}

		return false;
	}

	private boolean checkHideBeat() {
		if (this.getX() <= Constants.XPOS_BEAT_FLATDRAGON
				&& (mState == StatesFlyingDragon.HIDE || mState == StatesFlyingDragon.MOVE)) {
			return true;
		}
		return false;
	}

	public void updateTextureRegion(TiledTextureRegion pTextureRegion,
			boolean isReset) {
		super.updateTextureRegion(pTextureRegion, isReset);
		widthContain = pTextureRegion.getTileWidth() - 50;
		heightContain = pTextureRegion.getTileHeight() - 150;
	}

	public boolean isFire() {
		return isFire;
	}

	public void setMove() {
		this.isMove = true;
	}

	public void stopAttack() {
		this.isAttack = false;
	}

	public void moveBackNormal() {
		this.setVisible(true);
		if (isMoveBackNormal) {
			handler.setVelocity(
					this.getX() < Constants.XPOS_BEAT_FLATDRAGON ? -VELOCITY_X_MOVE_BACK_NORMAL
							: VELOCITY_X_MOVE_BACK_NORMAL,
					this.getY() > 200 ? -VELOCITY_Y_MOVE_BACK_NORMAL
							: VELOCITY_Y_MOVE_BACK_NORMAL);
			animate(durationMoveBackNormal, 0, 10, true);
			mState = StatesFlyingDragon.MOVE_BACK;
		} else
			handler.setVelocity(VELOCITY_X, VELOCITY_Y);
	}

	public void setMoveBackNormal(boolean isMovebackNormal) {
		this.isMoveBackNormal = isMovebackNormal;
	}

	public boolean isMoveBackNormal() {
		return isMoveBackNormal;
	}

	public StatesFlyingDragon getState() {
		return mState;
	}

	public void setFireSkill(boolean isFireSkill) {
		isFire = isFireSkill;
	}

	public boolean isAttack() {
		return isAttack;
	}

	public void setMoveBack() {
		this.isMoveBack = true;
	}

	private StatesFlyingDragon getMethodAttack() {
		int r = MathUtils.random(0, 2);

		if (r == 2) {
			return StatesFlyingDragon.FIRE;
		} else
			return StatesFlyingDragon.HIDE;
	}

	public void setState(StatesFlyingDragon pState) {
		this.mState = pState;
	}

	public void shirk() {
		float pY = MathUtils.random(70, 300);

		float distance = (float) (Math.sqrt(300 * 300 + pY * pY));
		float time = distance / 566;

		MoveModifier modifier = new MoveModifier(time, this.getX(),
				this.getX() + 300, this.getY(), pY);
		this.registerEntityModifier(modifier);
	}

	public void move() {
		if (changeTiledTextureRegion(StatesFlyingDragon.MOVE)) {
			this.updateTextureRegion(mTextureRegionMove, true);
		}
		if (changeState(StatesFlyingDragon.MOVE)) {
			handler.setVelocity(VELOCITY_X, VELOCITY_Y);
		}
		registerUpdateHandler(handler);
		isChecked = false;
		status = Constants.MOVE;
		isFire = false;
		this.animate(durationFly, 0, 10, true);
	}

	public void moveBack(final float xPos, final float yPos) {
		stopAnimation();
		isChecked = false;
		isAttack = false;
		this.setVisible(true);
		if (changeTiledTextureRegion(StatesFlyingDragon.MOVE_BACK))
			this.updateTextureRegion(mTextureRegionMove, true);
		mState = StatesFlyingDragon.MOVE_BACK;
		unregisterUpdateHandler(handler);
		MoveModifier modifier = new MoveModifier(300 / (xPos - 120),
				this.getX(), xPos, this.getY(), yPos);
		this.registerEntityModifier(modifier);
		this.setVisible(true);
	}

	public void fire() {

		if (changeTiledTextureRegion(StatesFlyingDragon.FIRE)) {
			this.updateTextureRegion(mAttackTextureRegion, true);
			changeState(StatesFlyingDragon.FIRE);
			this.animate(durationFireSkill, 0, 6, 0, new IAnimationListener() {
				
				@Override
				public void onAnimationEnd(AnimatedSprite arg0) {
					isMove = true;
					
				}
			});
		}
		status = Constants.ATTACK;
		tiledAttack = 4;
		isChecked = false;
		isFire = false;
	}

	public void die() {
		if (changeState(StatesFlyingDragon.DIE)) {
			isChecked = false;
			status = Constants.DIE;
			isFire = false;
			dieTime = System.currentTimeMillis();
			this.updateTextureRegion(mDieTextureRegion, true);
			this.animate(durationDie, false, new IAnimationListener() {

				@Override
				public void onAnimationEnd(AnimatedSprite arg0) {
					setVisible(false);
				}

			});
			unregisterUpdateHandler(handler);
		}
	}

	public long getDieTime() {
		return dieTime;
	}

	public boolean changeState(StatesFlyingDragon pState) {
		if (pState == mState)
			return false;
		mState = pState;
		return true;
	}

	private boolean changeTiledTextureRegion(StatesFlyingDragon pState) {
		if (pState.getTiledTextureRegion() == mState.getTiledTextureRegion())
			return false;
		return true;
	}

	public void disappear() {
		if (changeTiledTextureRegion(StatesFlyingDragon.HIDE)) {
			this.updateTextureRegion(mTextureRegionMove, true);
		}
		if (changeState(StatesFlyingDragon.HIDE)) {
			this.animate(durationFly);
			isChecked = false;
			isAttack = false;
			status = Constants.ATTACK;
			tiledAttack = 8;
		}
		isFire = false;
	}

//	private void moveBack() {
//		isMoveBack = false;
//		float yPos = MathUtils.random(80, 250);
//		MoveModifier modifier = new MoveModifier(1.0f, this.getX(), 850,
//				this.getY(), yPos);
//		this.registerEntityModifier(modifier);
//		move();
//	}

	public static enum StatesFlyingDragon {
		MOVE(0), MOVE_BACK(0), HIDE(0), HIDE_BEAT(0), FIRE(1), DIE(2);

		private int state;

		private StatesFlyingDragon(final int pTiledTextureRegion) {
			this.state = pTiledTextureRegion;
		}

		private int getTiledTextureRegion() {
			return state;
		}
	}

}
